package edu.gatech.cs2340.mule.model;
import java.awt.Point;


/**
 * 
 * This class takes care of the different transactions of resources and land between players
 * and between the store and the players.
 * 
 * @author Keegan Nesbitt
 *
 */
public class Transaction {

	/**
	 * 
	 * @param gameStoreInterface The interface to the store
	 * @param buyingPlayer The player buying the energy from the store
	 * @param resourceAmount The amount of energy the player is attempting to buy
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean buyEnergyFromStore(StoreInterface gameStoreInterface, Player buyingPlayer, int resourceAmount) {
		int energyCost = gameStoreInterface.calculateEnergyPurchasePrice(resourceAmount);
		if (buyingPlayer.getMoneyAmount() >= energyCost && gameStoreInterface.purchaseEnergy(resourceAmount)) {
			buyingPlayer.setMoneyAmount(-energyCost);
			buyingPlayer.setEnergyAmount(resourceAmount);
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @param gameStoreInterface The interface to the store
	 * @param buyingPlayer The player attempting to buy food
	 * @param resourceAmount The amount of food the player is attempting to buy
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean buyFoodFromStore(StoreInterface gameStoreInterface, Player buyingPlayer, int resourceAmount) {
		int foodCost = gameStoreInterface.calculateFoodPurchasePrice(resourceAmount);
		if (buyingPlayer.getMoneyAmount() >= foodCost && gameStoreInterface.purchaseFood(resourceAmount)) {
			buyingPlayer.setMoneyAmount(-foodCost);
			buyingPlayer.setFoodAmount(resourceAmount);
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @param gameStoreInterface The interface to the game's store
	 * @param buyingPlayer The player purchasing the smithore
	 * @param resourceAmount The amount of smithore the player is attempting to purchase
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean buySmithoreFromStore(StoreInterface gameStoreInterface, Player buyingPlayer, int resourceAmount) {
		int smithoreCost = gameStoreInterface.calculateSmithorePurchasePrice(resourceAmount);
		if (buyingPlayer.getMoneyAmount() >= smithoreCost && gameStoreInterface.purchaseSmithore(resourceAmount)) {
			buyingPlayer.setMoneyAmount(-smithoreCost);
			buyingPlayer.setSmithOreAmount(resourceAmount);
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @param gameStoreInterface The interface to the game's store
	 * @param buyingPlayer The player purchasing the mule
	 * @param muleType The type of the Mule to be purchased
	 * @return The Mule to be placed if it was purchased, otherwise null
	 */
	public static Mule buyMuleFromStore(StoreInterface gameStoreInterface, Player buyingPlayer, String muleType) {
		int muleCost = gameStoreInterface.calculateMulePurchasePrice(muleType);
		if(buyingPlayer.getMoneyAmount() >= muleCost && gameStoreInterface.canPurchaseMule()) {
			buyingPlayer.setMoneyAmount(-muleCost);
			Mule boughtMule = gameStoreInterface.purchaseMule(muleType);
			return boughtMule;
		}
		return null;
	}
	
	/**
	 * 
	 * @param gameStoreInterface The interface to the store
	 * @param sellingPlayer The player attempting to sell resources to the store
	 * @param resourceAmount The amount of energy the player is attempting to sell
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean sellEnergyToStore(StoreInterface gameStoreInterface, Player sellingPlayer, int resourceAmount) {
		int energyCost = gameStoreInterface.calculateEnergyPurchasePrice(resourceAmount);
		if (sellingPlayer.getEnergyAmount() >= resourceAmount) {
			sellingPlayer.setMoneyAmount(energyCost);
			sellingPlayer.setEnergyAmount(-resourceAmount);
			gameStoreInterface.tradeInEnergy(resourceAmount);
			return true;
		}
		return false;
	}
	

	/**
	 * 
	 * @param gameStoreInterface The interface to the game's store
	 * @param sellingPlayer The player attempting to sell food to the store
	 * @param resourceAmount The amount of food the player is attempting to sell
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean sellFoodToStore(StoreInterface gameStoreInterface, Player sellingPlayer, int resourceAmount) {
		int foodCost = gameStoreInterface.calculateFoodPurchasePrice(resourceAmount);
		if (sellingPlayer.getFoodAmount() >= resourceAmount){
			sellingPlayer.setMoneyAmount(foodCost);
			sellingPlayer.setFoodAmount(-resourceAmount);
			gameStoreInterface.tradeInFood(resourceAmount);
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @param gameStoreInterface The interface to the game's store
	 * @param sellingPlayer The player attempting to sell smithore
	 * @param resourceAmount The amount of smithore the player is attempting to sell
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean sellSmithoreToStore(StoreInterface gameStoreInterface, Player sellingPlayer, int resourceAmount) {
		int smithoreCost = gameStoreInterface.calculateSmithorePurchasePrice(resourceAmount);
		if (sellingPlayer.getSmithOreAmount() >= resourceAmount){
			sellingPlayer.setMoneyAmount(smithoreCost);
			sellingPlayer.setSmithOreAmount(-resourceAmount);
			gameStoreInterface.tradeInSmithore(resourceAmount);
			return true;
		}
		return false;

	}
	
	/**
	 * 
	 * @param gamePubInterface The PubInterface object to be used for the player to gamble
	 * @param gamblingPlayer The player gambling in the pub
	 */
	public static int gambleAtPub(PubInterface gamePubInterface, Player gamblingPlayer) {
		int bonus = gamePubInterface.calculateMoneyBonus();
		gamblingPlayer.setMoneyAmount(bonus);
		return bonus;
	}
	
	/**
	 * 
	 * Allows the player to purchase a map tile for no cost from the land office
	 * 
	 * @param landOfficeInterface The land office interface to get the land from
	 * @param buyingPlayer The player receiving the land grant
	 * @param location The location of the tile being granted
	 * @return True if the grant was successful, false otherwise
	 */
	public static boolean performLandGrant(LandOfficeInterface landOfficeInterface, Player buyingPlayer, Point location) {
		boolean isUnowned = landOfficeInterface.isUnowned(location);
		if(isUnowned) {
			landOfficeInterface.removeUnownedLand(location);
			buyingPlayer.addOwnedLand(location);
			return true;
		}
		else {
			return false;
		}
	}
	
	/**
	 * 
	 * Removes the specified tile from the unowned properties in the LandOffice
	 * and adds it to the specified player's inventory if the player has enough money
	 * for the transaction.
	 * 
	 * @param landOfficeInterface The land office interface to buy the land from
	 * @param buyingPlayer The player buying the land
	 * @param location The position of the tile being purchased
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean buyFromLandOffice(LandOfficeInterface landOfficeInterface, Player buyingPlayer, Point location) {
		int buyingPrice = landOfficeInterface.calculateBuyingPrice();
		boolean canAffordTransaction = buyingPlayer.canAffordTransaction(buyingPrice);
		boolean isUnowned = landOfficeInterface.isUnowned(location);
		
		if(canAffordTransaction && isUnowned) {
			landOfficeInterface.removeUnownedLand(location);
			buyingPlayer.addOwnedLand(location);
			buyingPlayer.setMoneyAmount(-buyingPrice);			
			return true;
		}
		else {
			return false;
		}
	}
	
	/**
	 * 
	 * Removes the specified tile from the player's owned land inventory and
	 * adds it to the unowned land in the LandOffice.
	 * 
	 * @param landOfficeInterface The land office interface to sell the land to
	 * @param sellingPlayer The player selling the land
	 * @param location The position of the property being sold
	 * @return True if the transaction was successful, false otherwise
	 */
	public static boolean sellToLandOffice(LandOfficeInterface landOfficeInterface, Player sellingPlayer, Point location) {
		int sellingPrice = landOfficeInterface.calculateSellingPrice();
		boolean isOwned = sellingPlayer.isOwned(location);
		
		if(isOwned) {
			sellingPlayer.removeOwnedLand(location);
			landOfficeInterface.addUnownedLand(location);
			sellingPlayer.setMoneyAmount(sellingPrice);
			return true;
		}
		else {
			return false;
		}
	}
	
} // end Transaction class
